import requests
import json
import os
import random
import re
from typing import Dict, Any, List, Optional
from config import XINGHE_API_KEY, XINGHE_BASE_URL, XINGHE_MODEL

class RustQAAgent:
    """Rust智能问答代理，用于生成Rust相关概念的解释"""
    
    def __init__(self):
        """初始化Rust问答代理"""
        self.api_key = XINGHE_API_KEY
        self.base_url = XINGHE_BASE_URL
        self.model = XINGHE_MODEL
        
        # 检查API密钥是否配置
        if not self.api_key or not self.base_url:
            self.use_mock_data = True
            print("警告: 未配置星河大模型API密钥或URL，将使用模拟数据")
        else:
            self.use_mock_data = False
    
    def _format_rust_code(self, code: str) -> str:
        """
        对Rust代码进行简单的格式化，增加换行。
        """
        # 移除可能存在于代码块开头和结尾的多余空白
        code = code.strip()
        
        # 在分号和花括号后添加换行
        code = re.sub(r';', ';\n', code)
        code = re.sub(r'{', '{\n', code)
        code = re.sub(r'}', '}\n', code)
        
        # 处理缩进
        formatted_code = []
        indentation_level = 0
        for line in code.split('\n'):
            line = line.strip()
            if not line:
                continue
            
            if '}' in line and indentation_level > 0:
                indentation_level -= 1
            
            formatted_code.append('    ' * indentation_level + line)
            
            if '{' in line:
                indentation_level += 1
        
        return '\n'.join(formatted_code)

    def _call_xinghe_api(self, question: str, classification: str) -> Dict[str, Any]:
        """
        调用星河大模型API
        
        Args:
            question: 用户问题
            classification: 问题分类
            
        Returns:
            API响应结果
        """
        # 构建系统提示词
        system_prompt = f"""
你是一个专业的Rust编程语言学习助手。请严格按照以下格式和要求回答用户的问题。

### 回答格式要求

1.  **基本概念**：
    *   首先，用简洁明了的语言解释问题所涉及的核心概念。
    *   这部分内容使用二级标题 `## 1. 基本概念`。

2.  **函数签名**：
    *   如果适用，提供与概念相关的核心函数或Trait的签名。
    *   将每个签名都放入独立的Rust代码块中。
    *   在代码块上方说明该签名的作用。
    *   这部分内容使用二级标题 `## 2. 函数签名`。

3.  **核心特性**：
    *   提供与概念相关的核心特性和应用场景的说明。
    *   可以包含简短的代码示例来说明关键点。
    *   将代码示例放入Rust代码块中。
    *   确保代码块中的代码（包括注释）都有良好的换行和缩进，不要拥挤在一起。
    *   这部分内容使用二级标题 `## 3. 核心特性`。


"""
        
        # 构建请求头 - 添加Authorization头和日期头
        import datetime
        now = datetime.datetime.utcnow()
        date_str = now.strftime('%a, %d %b %Y %H:%M:%S GMT')
        
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"token {self.api_key}",
            "Date": date_str,
            "x-bce-date": date_str
        }
        
        # 构建请求数据
        data = {
            "model": self.model,
            "messages": [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": question}
            ],
            "temperature": 0.7,
            "max_tokens": 2000,
            "stream": False
        }
        
        # 发送请求 - 使用正确的API端点和认证方式
        response = requests.post(
            f"{self.base_url}/chat/completions",
            headers=headers,
            json=data,
            timeout=30
        )
        
        # 解析响应
        if response.status_code == 200:
            result = response.json()
            
            # 确保正确提取content字段
            if "choices" in result and len(result["choices"]) > 0 and "message" in result["choices"][0]:
                answer = result["choices"][0]["message"]["content"]
            elif "result" in result:
                answer = result["result"]
            else:
                # 如果格式不符合预期，打印整个响应并使用备用方案
                print(f"API响应格式不符合预期: {result}")
                answer = str(result)

            # 格式化代码块
            def format_code_block(match):
                lang = match.group(1)
                code = match.group(2)
                if lang.lower() == 'rust':
                    formatted_code = self._format_rust_code(code)
                    return f"```{lang}\n{formatted_code}\n```"
                return match.group(0)

            answer = re.sub(r"```(\w+)\n(.*?)```", format_code_block, answer, flags=re.DOTALL)
            
            return {
                "answer_markdown": answer,
                "classification": classification,
                "sources": ["星河大模型API"]
            }
        else:
            raise Exception(f"API请求失败: {response.status_code}, {response.text}")
    
    def answer_question(self, user_id: str, question: str) -> Dict[str, Any]:
        """
        回答Rust相关问题
        
        Args:
            user_id: 用户ID
            question: 用户问题
            
        Returns:
            包含回答、分类和来源的字典
        """
        # 对问题进行分类
        classification = self._classify_question(question)
        
        # 如果配置了API且不使用模拟数据，调用星河大模型
        if not self.use_mock_data:
            try:
                result = self._call_xinghe_api(question, classification)
                return {
                    "status": "success",
                    "answer": result["answer_markdown"],
                    "answer_markdown": result["answer_markdown"],
                    "classification": result["classification"],
                    "sources": result["sources"]
                }
            except Exception as e:
                print(f"调用星河大模型API失败: {e}")
                print("回退到模拟数据模式")
                # 如果API调用失败，回退到模拟数据
                mock_result = self._generate_mock_answer(question, classification)
                return {
                    "status": "success",
                    "answer": mock_result["answer_markdown"],
                    "answer_markdown": mock_result["answer_markdown"],
                    "classification": mock_result["classification"],
                    "sources": mock_result["sources"]
                }
        else:
            # 使用模拟数据
            mock_result = self._generate_mock_answer(question, classification)
            return {
                "status": "success",
                "answer": mock_result["answer_markdown"],
                "answer_markdown": mock_result["answer_markdown"],
                "classification": mock_result["classification"],
                "sources": mock_result["sources"]
            }
    
    def _generate_mock_answer(self, question: str, classification: str) -> Dict[str, Any]:
        """
        生成模拟回答
        
        Args:
            question: 用户问题
            classification: 问题分类
            
        Returns:
            包含回答、分类和来源的字典
        """
        # 根据问题关键词生成不同的模拟回答
        question_lower = question.lower()
        
        if "所有权" in question or "ownership" in question_lower:
            answer = """
# Rust所有权系统

Rust的所有权系统是其最独特的特性之一，它确保了内存安全而无需垃圾回收器。

## 所有权规则

1. Rust中的每个值都有一个所有者
2. 同一时间只能有一个所有者
3. 当所有者离开作用域时，值将被丢弃

## 示例代码

```rust
fn main() {
    let s1 = String::from("hello");  // s1拥有字符串
    let s2 = s1;                     // 所有权转移给s2
    // println!("{}", s1);           // 错误！s1不再有效
    println!("{}", s2);              // 正确
}
```

## 借用与引用

如果不想转移所有权，可以使用引用：

```rust
fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1); // 传递引用
    println!("'{}' 的长度是 {}", s1, len); // s1仍然有效
}

fn calculate_length(s: &String) -> usize {
    s.len()
} // s离开作用域，但没有所有权，所以不会丢弃
```
"""
        elif "借用" in question or "borrowing" in question_lower:
            answer = """
# Rust借用检查器

Rust的借用检查器在编译时确保引用的安全性，防止悬垂指针和数据竞争。

## 借用规则

1. 在任意给定时间，要么只能有一个可变引用，要么只能有多个不可变引用
2. 引用必须总是有效的

## 示例代码

```rust
fn main() {
    let mut s = String::from("hello");
    
    let r1 = &s; // 没问题
    let r2 = &s; // 没问题
    println!("r1: {}, r2: {}", r1, r2);
    // r1和r2在此之后不再使用
    
    let r3 = &mut s; // 没问题
    println!("r3: {}", r3);
}
```

## 悬垂引用

Rust编译器会防止悬垂引用：

```rust
fn main() {
    let reference_to_nothing = dangle();
}

fn dangle() -> &String { // 错误
    let s = String::from("hello");
    &s // 返回局部变量的引用
} // s离开作用域并被丢弃
```

正确的做法是返回值本身：

```rust
fn dangle() -> String { // 正确
    let s = String::from("hello");
    s // 返回值的所有权
}
```
"""
        elif "生命周期" in question or "lifetimes" in question_lower:
            answer = """
# Rust生命周期

生命周期是Rust中的一种机制，用于确保引用在其所指向的数据有效期间始终有效。

## 生命周期注解语法

生命周期参数以撇号(')开头，通常使用小写字母：

```rust
&'a str     // 带有生命周期'a的字符串引用
&'a mut T   // 带有生命周期'a的可变引用
```

## 函数签名中的生命周期

```rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}
```

## 结构体中的生命周期

```rust
struct ImportantExcerpt<'a> {
    part: &'a str,
}

fn main() {
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().expect("Could not find a '.'");
    
    let i = ImportantExcerpt {
        part: first_sentence,
    };
}
```

## 生命周期省略规则

1. 每个引用参数都有自己的生命周期参数
2. 如果只有一个输入生命周期参数，那么所有输出生命周期都使用它
3. 如果有多个输入生命周期参数，但其中一个是&self或&mut self，那么所有输出生命周期都使用self的生命周期
"""
        elif "trait" in question_lower or "特性" in question:
            answer = """
# Rust Trait系统

Trait是Rust中定义共享行为的方式，类似于其他语言中的接口。

## 定义Trait

```rust
pub trait Summary {
    fn summarize(&self) -> String;
    
    // 默认实现
    fn summarize_verbose(&self) -> String {
        format!("(Read more from {}...)", self.summarize())
    }
}
```

## 实现Trait

```rust
pub struct NewsArticle {
    pub headline: String,
    pub location: String,
    pub author: String,
    pub content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({})", self.headline, self.author, self.location)
    }
}
```

## Trait作为参数

```rust
pub fn notify(item: &impl Summary) {
    println!("Breaking news! {}", item.summarize());
}

// 或者使用trait bound语法
pub fn notify<T: Summary>(item: &T) {
    println!("Breaking news! {}", item.summarize());
}
```

## 返回实现了Trait的类型

```rust
fn returns_summarizable() -> impl Summary {
    Tweet {
        username: String::from("horse_ebooks"),
        content: String::from("of course, as you probably already know, people"),
        reply: false,
        retweet: false,
    }
}
```
"""
        elif "错误处理" in question or "error" in question_lower:
            answer = """
# Rust错误处理

Rust提供了强大的错误处理机制，主要通过Result<T, E>和Option<T>类型。

## Result类型

```rust
enum Result<T, E> {
    Ok(T),
    Err(E),
}
```

## 使用Result

```rust
use std::fs::File;

fn main() {
    let f = File::open("hello.txt");
    
    let f = match f {
        Ok(file) => file,
        Err(error) => {
            panic!("打开文件出错: {:?}", error)
        },
    };
}
```

## 使用match处理错误

```rust
use std::fs::File;
use std::io::Read;

fn read_username_from_file() -> Result<String, std::io::Error> {
    let f = File::open("username.txt");
    
    let mut f = match f {
        Ok(file) => file,
        Err(e) => return Err(e),
    };
    
    let mut s = String::new();
    
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}
```

## 使用?操作符简化错误处理

```rust
use std::fs::File;
use std::io::Read;
use std::io;

fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = File::open("username.txt")?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

// 更简洁的写法
fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();
    File::open("username.txt")?.read_to_string(&mut s)?;
    Ok(s)
}
```

## Option类型

```rust
enum Option<T> {
    Some(T),
    None,
}
```

```rust
fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        Some(i) => Some(i + 1),
        None => None,
    }
}
```
"""
        elif "并发" in question or "concurrency" in question_lower:
            answer = """
# Rust并发编程

Rust的并发编程特性使其能够编写安全且高效的并发代码，无需担心数据竞争。

## 线程

```rust
use std::thread;
use std::time::Duration;

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {} from the spawned thread!", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!("hi number {} from the main thread!", i);
        thread::sleep(Duration::from_millis(1));
    }

    handle.join().unwrap();
}
```

## 使用move闭包

```rust
use std::thread;

fn main() {
    let v = vec![1, 2, 3];
    
    let handle = thread::spawn(move || {
        println!("Here's a vector: {:?}", v);
    });
    
    handle.join().unwrap();
}
```

## 通道(Channels)

```rust
use std::sync::mpsc;
use std::thread;

fn main() {
    let (tx, rx) = mpsc::channel();
    
    thread::spawn(move || {
        let val = String::from("hi");
        tx.send(val).unwrap();
    });
    
    let received = rx.recv().unwrap();
    println!("Got: {}", received);
}
```

## 共享内存

```rust
use std::sync::{Mutex, Arc};
use std::thread;

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];
    
    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }
    
    for handle in handles {
        handle.join().unwrap();
    }
    
    println!("Result: {}", *counter.lock().unwrap());
}
```
"""
        elif "宏" in question or "macro" in question_lower:
            answer = """
# Rust宏系统

Rust的宏系统是一种在编译时进行代码生成的强大工具，可以减少重复代码和实现元编程。

## 声明式宏(macro_rules!)

```rust
macro_rules! say_hello {
    () => {
        println!("Hello, World!");
    };
}

fn main() {
    say_hello!(); // 输出: Hello, World!
}
```

## 带参数的宏

```rust
macro_rules! create_function {
    ($func_name:ident) => {
        fn $func_name() -> &'static str {
            stringify!($func_name)
        }
    };
}

create_function!(foo);

fn main() {
    println!("{}", foo()); // 输出: foo
}
```

## 多种模式的宏

```rust
macro_rules! calculate {
    // 单个表达式
    (eval $e:expr) => {{
        {
            let val: usize = $e;
            println!("{} = {}", stringify!{$e}, val);
        }
    }};
    
    // 多个表达式
    (eval $e:expr, $(eval $es:expr),+) => {{
        calculate! { eval $e }
        calculate! { $(eval $es),+ }
    }};
}

fn main() {
    calculate! { eval 1 + 2 }
    calculate! { eval (1 + 2) * (3 / 4) }
}
```

## 过程式宏

### 自定义派生宏

```rust
use proc_macro::TokenStream;
use quote::quote;
use syn;

#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    // 构建AST并实现HelloMacro trait
    let ast = syn::parse(input).unwrap();
    impl_hello_macro(&ast)
}

fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream {
    let name = &ast.ident;
    let gen = quote! {
        impl HelloMacro for #name {
            fn hello_macro() {
                println!("Hello, Macro! My name is {}", stringify!(#name));
            }
        }
    };
    gen.into()
}
```
"""
        elif "异步" in question or "async" in question_lower:
            answer = """
# Rust异步编程

Rust的异步编程通过Future、async/await语法提供了一种高效处理并发I/O操作的方式。

## Future和async/await

```rust
use std::future::Future;

async fn hello_world() {
    println!("hello, world!");
}

fn main() {
    let future = hello_world(); // 返回一个Future
    // 需要一个执行器来运行Future
}
```

## 使用async-std运行时

```rust
use async_std::task;

async fn say_world() {
    println!("world");
}

fn main() {
    task::block_on(say_world());
}
```

## 异步函数

```rust
use async_std::task;
use async_std::net::TcpStream;
use async_std::io;

async fn fetch_url(url: &str) -> io::Result<String> {
    let mut stream = TcpStream::connect(url).await?;
    let mut buffer = String::new();
    
    stream.read_to_string(&mut buffer).await?;
    
    Ok(buffer)
}

fn main() {
    task::block_on(async {
        match fetch_url("example.com:80").await {
            Ok(content) => println!("收到内容: {}", content),
            Err(e) => println!("错误: {}", e),
        }
    });
}
```

## 并发执行多个异步任务

```rust
use async_std::task;
use futures::future::join_all;

async fn task1() -> String {
    println!("任务1开始");
    task::sleep(std::time::Duration::from_secs(1)).await;
    "任务1完成".to_string()
}

async fn task2() -> String {
    println!("任务2开始");
    task::sleep(std::time::Duration::from_secs(2)).await;
    "任务2完成".to_string()
}

async fn run_all() {
    let tasks = vec![task1(), task2()];
    let results = join_all(tasks).await;
    
    for result in results {
        println!("{}", result);
    }
}

fn main() {
    task::block_on(run_all());
}
```

## Stream处理

```rust
use futures::stream::{self, StreamExt};

async fn process_stream() {
    let mut stream = stream::iter(vec![1, 2, 3, 4, 5]);
    
    while let Some(value) = stream.next().await {
        println!("处理值: {}", value);
    }
}

fn main() {
    task::block_on(process_stream());
}
```
"""
        else:
            answer = f"""
# 关于Rust的问题

您的问题是: {question}

这是一个关于Rust编程语言的问题。Rust是一种系统编程语言，注重安全、速度和并发。

## Rust的主要特点

1. **内存安全**: 无需垃圾回收器即可保证内存安全
2. **并发安全**: 编译时防止数据竞争
3. **零成本抽象**: 高级抽象不会降低运行时性能
4. **实用的错误处理**: 通过Result和Option类型处理错误
5. **模式匹配**: 强大的控制流工具
6. **类型推断**: 编译器能推断出许多类型

## 学习资源

- [官方文档](https://doc.rust-lang.org/)
- [Rust by Example](https://doc.rust-lang.org/rust-by-example/)
- [The Rust Book](https://doc.rust-lang.org/book/)

如果您有更具体的问题，请随时提问！
"""
        
        return {
            "answer_markdown": answer,
            "classification": classification["label"] if isinstance(classification, dict) else classification,
            "sources": ["模拟数据"]
        }
    
    def _classify_question(self, question: str) -> Dict[str, any]:
        """
        分类用户问题
        
        Args:
            question: 用户问题
            
        Returns:
            分类结果字典
        """
        question_lower = question.lower()
        
        # 简单的关键词匹配分类
        if any(word in question_lower for word in ["你好", "hello", "hi", "您好"]):
            return {"label": "greeting", "confidence": 0.9}
        elif any(word in question_lower for word in ["什么是", "定义", "define", "解释"]):
            return {"label": "definition", "confidence": 0.8}
        elif any(word in question_lower for word in ["如何", "怎么", "how to", "用法", "使用"]):
            return {"label": "usage", "confidence": 0.8}
        elif any(word in question_lower for word in ["错误", "error", "bug", "问题", "修复"]):
            return {"label": "error_debug", "confidence": 0.8}
        elif any(word in question_lower for word in ["区别", "比较", "对比", "vs", "difference"]):
            return {"label": "comparison", "confidence": 0.8}
        else:
            return {"label": "faq", "confidence": 0.7}
    
    def get_rust_topics(self) -> List[str]:
        """
        获取Rust常见主题列表
        
        Returns:
            Rust主题列表
        """
        return [
            "所有权(Ownership)",
            "借用(Borrowing)",
            "生命周期(Lifetimes)",
            "特征(Traits)",
            "模式匹配(Pattern Matching)",
            "错误处理(Error Handling)",
            "闭包(Closures)",
            "并发编程(Concurrency)",
            "宏(Macros)",
            "迭代器(Iterators)"
        ]
    
    def generate_topic_questions(self, topic: str) -> List[str]:
        """
        为特定主题生成示例问题
        
        Args:
            topic: Rust主题
            
        Returns:
            示例问题列表
        """
        topic_questions = {
            "所有权(Ownership)": [
                "什么是Rust的所有权系统？",
                "Rust中的移动语义是什么？",
                "Copy和Clone trait有什么区别？"
            ],
            "借用(Borrowing)": [
                "Rust中的借用规则是什么？",
                "什么是悬垂指针？Rust如何避免？",
                "可变引用和不可变引用有什么区别？"
            ],
            "生命周期(Lifetimes)": [
                "为什么Rust需要生命周期？",
                "如何标注函数的生命周期？",
                "静态生命周期'static是什么意思？"
            ],
            "特征(Traits)": [
                "什么是Rust的trait？",
                "如何实现自定义trait？",
                "trait对象是什么？"
            ],
            "模式匹配(Pattern Matching)": [
                "Rust的match表达式如何工作？",
                "什么是解构模式？",
                "如何使用if let和while let？"
            ],
            "错误处理(Error Handling)": [
                "Rust中的Result和Option有什么区别？",
                "如何使用?操作符？",
                "什么是panic!和unwrap()？"
            ],
            "闭包(Closures)": [
                "什么是Rust的闭包？",
                "闭包如何捕获环境变量？",
                "闭包作为函数参数如何使用？"
            ],
            "并发编程(Concurrency)": [
                "Rust如何实现线程安全的并发？",
                "什么是Arc和Mutex？",
                "如何使用通道进行线程间通信？"
            ],
            "宏(Macros)": [
                "Rust中的声明式宏和过程宏有什么区别？",
                "如何编写自定义宏？",
                "宏展开的过程是怎样的？"
            ],
            "迭代器(Iterators)": [
                "什么是Rust的迭代器？",
                "如何创建自定义迭代器？",
                "迭代器适配器有哪些？"
            ]
        }
        
        return topic_questions.get(topic, [f"关于{topic}的一些问题"])